package com.shanghaionstar.utils;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;

import com.onstar.cn.common.util.Constants;
import com.onstar.cn.common.util.PreferencesUtls;
import com.onstar.cn.framework.mvp.base.core.AppScheduler;
import com.onstar.cn.framework.utils.RxBus;
import com.onstar.cn.framework.utils.RxSubscriptions;
import com.onstar.cn.rxconstants.RxConstants;
import com.shanghaionstar.OnstarApplication;
import com.shanghaionstar.R;
import com.shanghaionstar.iview.ILoginAndOutListener;
import com.shanghaionstar.iview.ILoginListener;
import com.shanghaionstar.login.LoginActivity;
import com.shanghaionstar.login.service.LoginTransformHelper;

import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.functions.Action1;
import rx.functions.Func1;

import static com.shanghaionstar.login.service.LoginTransformHelper.CACHE_STATE_ERROR;
import static com.shanghaionstar.login.service.LoginTransformHelper.CACHE_STATE_EXPIRED;
import static com.shanghaionstar.login.service.LoginTransformHelper.CACHE_STATE_NOCACHE;
import static com.shanghaionstar.login.service.LoginTransformHelper.CACHE_STATE_NORMAL;
import static com.shanghaionstar.login.service.LoginTransformHelper.CACHE_STATE_UPDATE;

/**
 * 在操作前检查是否登录，登陆后自动执行此次操作
 * Created by 6335yz on 2016/7/1.
 */
public class LoginUtil {

    private Subscription subscription;
    private Subscription mLoginOutRx;

    public void loginAndActionCallBack(final Context context, final int actionName, final ILoginListener iLoginListener, final Bundle bundle) {
        loginAndAction(context, new Action1() {
            @Override
            public void call(Object o) {
                //由于权限相关问题，登录成功后只需要返回上级页面无需跳转当前Click的Event
                iLoginListener.onLogin(ApplicationUtil.getInstance().isLogin() && actionName != RxConstants.DISCOVER_PAGE ? bundle : null, RxConstants.ACTION_SUCCESS);
                cancelSubscribe();
            }
        }, new Action1() {
            @Override
            public void call(Object o) {
                iLoginListener.onLogin(bundle, RxConstants.ACTION_FAILURE);
                cancelSubscribe();
            }
        }, actionName);
    }

    private Subscription mLoginRx;

    public void registLoginResult(final ILoginListener iLoginListener) {
        mLoginRx = RxBus.getDefault().toObserverable(RxConstants.ALL_PAGE_REFRESH, String.class).subscribeOn(new AppScheduler().backgroundThread())
                .observeOn(new AppScheduler().mainThread()).subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        iLoginListener.onLogin(null, RxConstants.ACTION_SUCCESS);
                        cancelSubscribe();
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        iLoginListener.onLogin(null, RxConstants.ACTION_FAILURE);
                        cancelSubscribe();
                    }
                });
        RxSubscriptions.add(mLoginRx);
    }

//    private void loginAndAction(Context context, Action1 action, Action1 errorAction, int actionName) {
//        if (ApplicationUtil.getInstance().isLogin()) {
//            Observable.create(new Observable.OnSubscribe<Object>() {
//                @Override
//                public void call(Subscriber<? super Object> subscriber) {
//                    subscriber.onNext(new Object());
//                }
//            }).subscribe(action, errorAction);
//        } else {
//            context.startActivity(new Intent(context, LoginActivity.class));
//            loginCallBack(action, errorAction, actionName);
//        }
//    }

    /**
     * 包含错误返回
     *
     * @param actionName 来自rxconstants.java
     * @param context
     * @param action
     */
    private void loginAndAction(Context context, Action1 action, Action1 errorAction, int actionName) {
        int state = OnstarApplication.getApplication().getmLoginState();
        if (state == CACHE_STATE_ERROR) {
            String subscriberJson = PreferencesUtls.getInstance(context).getString(Constants.AUTH_USER_PROFILE, "");
            if (!TextUtils.isEmpty(subscriberJson)) {
                long cacheTime = PreferencesUtls.getInstance(context).getLong(Constants.AUTH_USER_PROFILE_TIME, -1);
                if (LoginTransformHelper.detectCacheExpiration(cacheTime)) {
                    AlertDialogUtil.showAlertDialog(context, context.getString(R.string.dialog_warning),
                            context.getString(R.string.login_state_failed));
                } else {
                    Observable.create(new Observable.OnSubscribe<Object>() {
                        @Override
                        public void call(Subscriber<? super Object> subscriber) {
                            subscriber.onNext(new Object());
                        }
                    }).subscribe(action, errorAction);
                }
            } else {
                AlertDialogUtil.showAlertDialog(context, context.getString(R.string.dialog_warning),
                        context.getString(R.string.login_state_failed));
            }

        } else if (state == CACHE_STATE_NOCACHE) {
            AlertDialogUtil.showAlertDialog(context, context.getString(R.string.dialog_warning),
                    context.getString(R.string.login_state_nocache_tip));
        } else if (ApplicationUtil.getInstance().isLogin()) {
            switch (state) {
                case CACHE_STATE_EXPIRED:
                    AlertDialogUtil.showAlertDialog(context, context.getString(R.string.dialog_warning),
                            context.getString(R.string.login_state_nocache_tip));
                    break;
                case CACHE_STATE_NORMAL:
                case CACHE_STATE_UPDATE:
                default:
                    Observable.create(new Observable.OnSubscribe<Object>() {
                        @Override
                        public void call(Subscriber<? super Object> subscriber) {
                            subscriber.onNext(new Object());
                        }
                    }).subscribe(action, errorAction);
                    break;
            }
        } else if (ApplicationUtil.getInstance().isAutoLogings()) {
            AlertDialogUtil.showAlertDialog(context, context.getString(R.string.dialog_warning),
                    context.getString(R.string.loading));
        } else {
            Intent intent = new Intent(context, LoginActivity.class);
            intent.putExtra(RxConstants.ACTION_NAME, actionName);
            context.startActivity(intent);
            loginCallBack(action, errorAction, actionName);
        }
    }

    private void loginCallBack(Action1 action, Action1 errorAction, int actionName) {
        subscription = RxBus.getDefault().toObserverable(actionName, String.class).filter(new Func1<String, Boolean>() {
            @Override
            public Boolean call(String s) {
                return RxConstants.LOGIN_SUCCESS.equals(s);
            }
        }).subscribeOn(new AppScheduler().backgroundThread())
                .observeOn(new AppScheduler().mainThread())
                .subscribe(action, errorAction);
    }

    private void cancelSubscribe() {
        if (subscription != null) {
            subscription.unsubscribe();
        }
        RxSubscriptions.remove(mLoginRx);
    }

    public void loginAndOutShowView(Context context, final ILoginAndOutListener iLoginListener) {
        RxSubscriptions.remove(mLoginOutRx);
        mLoginOutRx = RxBus.getDefault()
                .toObserverable(RxConstants.ALL_PAGE_REFRESH, String.class)
                .filter(new Func1<String, Boolean>() {
                    @Override
                    public Boolean call(String s) {
                        return s != null && (s.equalsIgnoreCase(RxConstants.LOGIN_OUT) || s.equalsIgnoreCase(RxConstants.LOGIN_SUCCESS));
                    }
                })
                .subscribeOn(new AppScheduler().backgroundThread())
                .observeOn(new AppScheduler().mainThread())
                .subscribe(createLoginOutAction(context, iLoginListener));
                RxSubscriptions.add(mLoginOutRx);
                if (ApplicationUtil.getInstance().isLogin()) {
                    iLoginListener.onLogin();
                } else {
                    iLoginListener.onLoginOut();
                }

//
//            Observable.create(new Observable.OnSubscribe<Object>() {
//                @Override
//                public void call(Subscriber<? super Object> subscriber) {
//                    subscriber.onNext(new Object());
//                }
//            }).subscribe(createLoginOutAction(context, iLoginListener));
    }

    public void clearLoginOrOut(){
        RxSubscriptions.remove(mLoginOutRx);
    }

    public void clear() {
        if (subscription != null) {
            subscription.unsubscribe();
            subscription = null;
        }
        RxSubscriptions.remove(mLoginOutRx);
        cancelSubscribe();
    }

    private Action1 createLoginOutAction(final Context context, final ILoginAndOutListener iLoginListener) {
        return new Action1() {
            @Override
            public void call(Object o) {
                if (ApplicationUtil.getInstance().isLogin()) {
                    iLoginListener.onLogin();
                } else {
                    iLoginListener.onLoginOut();
                }
            }
        };
    }
}
